﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace xO
{
    public enum Winner
	{
	    None, X, O
	}

    public partial class Game : Form
    {
         private string[] lastmoves;
         private Label[] board;
         private Winner winner;
         private Player player1;
         private Player player2;
         private bool first;
         private bool gameOver;

         public Winner Winner
         {
             get { return winner; }
             set { winner = value; }
         }
 
        public Game()
        {
            InitializeComponent();
            lastmoves = new string[9] { null, null, null, null, null, null, null, null, null};
            winner = Winner.None;
            board = new Label[] { label1, label2, label3, label4, label5, label6, label7, label8, label9};
            againstComputerToolStripMenuItem.Select();
            player1 = new Human("X");
            player2 = new AI("O");
            first = true;
            gameOver = false;
            timer1.Enabled = true;
            Play(player1, player2);
        }

        public List<int> GetFreePositions()
        {
            List<int> moves = new List<int>();
            for (int i = 0; i < lastmoves.Count(); i++)
            {
                if (lastmoves[i] == null)
                {
                    moves.Add(i);
                }
            }
            return moves;
        }

        public void Mark(string marker, int pos)
        {
            lastmoves[pos] = marker;
        }

        public void RevertLastMove(int moveToRevert)
        {
            lastmoves[moveToRevert] = null;
            winner = Winner.None;
        }

        public bool IsGameover()
        {
            int[][] winPositions = new int[][] { new int[3] { 0, 1, 2 }, new int[] { 3, 4, 5 }, new int[] { 6, 7, 8 }, new int[] { 0, 3, 6 }, new int[] { 1, 4, 7 }, new int[] { 2, 5, 8 }, new int[] { 0, 4, 8 }, new int[] { 2, 4, 6 } };
            foreach (int[] niz in winPositions)
            {
                if (lastmoves[niz[0]] != null && lastmoves[niz[0]] == lastmoves[niz[1]]
                    && lastmoves[niz[0]] == lastmoves[niz[2]])
                {
                    winner = (Winner)Enum.Parse(typeof(Winner), lastmoves[niz[0]]);
                    return true;
                }   
            }
            if (!lastmoves.Contains(null))
            {
                winner = Winner.None;
                return true;
            }
            return false;
        }

        public void Play(Player player1, Player player2)
        {
            for (int i = 0; i < 9; i++)
            {
                board[i].Text = lastmoves[i];
                if (lastmoves[i] != null)
                {
                    board[i].Enabled = false;
                }
            }
            if (first)
            {
                statusLabel2.Text = "Player 1";
            }
            else
            {
                statusLabel2.Text = "Player 2";
            }  
            if (IsGameover())
            {
                gameOver = true;
                timer1.Stop();
                statusLabel2.Text = "Winner " + winner.ToString();
                MessageBox.Show("Winner " + winner.ToString());
                foreach (Label l in board)
                {
                    l.Enabled = false;
                }
            }
        }

        int minut = 0, sekund = 0, stotinka = 0;

        private void clock()
        {
            stotinka += 2;
            if (stotinka == 100)
            {
                stotinka = 0;
                sekund += 1;
            }
            if (sekund == 60)
            {
                sekund = 0;
                minut += 1;
            }

            
            timeStatusLabel.Text = "time: " + minut + ":" + sekund;
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            clock();
        }

        private void tableLayoutPanel1_Paint(object sender, PaintEventArgs e)
        {
            
        }

        private void label1_Click(object sender, EventArgs e)
        {
            if (first)
            {
                player1.Move(this, 0);
                first = false;
                Play(player1,player2);
                if (!gameOver && player2.GetType() == typeof(AI))
                {
                    player2.Move(this, 0);
                    first = true;
                    Play(player1, player2);
                }
            }
            else
            {
                player2.Move(this, 0);
                first = true;
                Play(player1, player2);
            }
            //Play(player1, player2);
            
        }

        private void label2_Click(object sender, EventArgs e)
        {
            if (first)
            {
                player1.Move(this, 1);
                first = false;
                Play(player1, player2);
                if (!gameOver && player2.GetType() == typeof(AI))
                {
                    player2.Move(this, 0);
                    first = true;
                    Play(player1, player2);
                }
            }
            else
            {
                player2.Move(this, 1);
                first = true;
                Play(player1, player2);
            }
            //Play(player1, player2);
        }

        private void label3_Click(object sender, EventArgs e)
        {
            if (first)
            {
                player1.Move(this, 2);
                first = false;
                Play(player1, player2);
                if (!gameOver && player2.GetType() == typeof(AI))
                {
                    player2.Move(this, 0);
                    first = true;
                    Play(player1, player2);
                }
            }
            else
            {
                player2.Move(this, 2);
                first = true;
                Play(player1, player2);
            }
            //Play(player1, player2);
        }

        private void label4_Click(object sender, EventArgs e)
        {
            if (first)
            {
                player1.Move(this, 3);
                first = false;
                Play(player1, player2);
                if (!gameOver && player2.GetType() == typeof(AI))
                {
                    player2.Move(this, 0);
                    first = true;
                    Play(player1, player2);
                }
            }
            else
            {
                player2.Move(this, 3);
                first = true;
                Play(player1, player2);
            }
            //Play(player1, player2);
        }

        private void label5_Click(object sender, EventArgs e)
        {
            if (first)
            {
                player1.Move(this, 4);
                first = false;
                Play(player1, player2);
                if (!gameOver && player2.GetType() == typeof(AI))
                {
                    player2.Move(this, 0);
                    first = true;
                    Play(player1, player2);
                }
            }
            else
            {
                player2.Move(this, 4);
                first = true;
                Play(player1, player2);
            }
            //Play(player1, player2);
        }

        private void label6_Click(object sender, EventArgs e)
        {
            if (first)
            {
                player1.Move(this, 5);
                first = false;
                Play(player1, player2);
                if (!gameOver && player2.GetType() == typeof(AI))
                {
                    player2.Move(this, 0);
                    first = true;
                    Play(player1, player2);
                }
            }
            else
            {
                player2.Move(this, 5);
                first = true;
                Play(player1, player2);
            }
            //Play(player1, player2);
        }

        private void label7_Click(object sender, EventArgs e)
        {
            if (first)
            {
                player1.Move(this, 6);
                first = false;
                Play(player1, player2);
                if (!gameOver && player2.GetType() == typeof(AI))
                {
                    player2.Move(this, 0);
                    first = true;
                    Play(player1, player2);
                }
            }
            else
            {
                player2.Move(this, 6);
                first = true;
                Play(player1, player2);
            }
            //Play(player1, player2);
        }

        private void label8_Click(object sender, EventArgs e)
        {
            if (first)
            {
                player1.Move(this, 7);
                first = false;
                Play(player1, player2);
                if (!gameOver && player2.GetType() == typeof(AI))
                {
                    player2.Move(this, 0);
                    first = true;
                    Play(player1, player2);
                }
            }
            else
            {
                player2.Move(this, 7);
                first = true;
                Play(player1, player2);
            }
            //Play(player1, player2);
        }

        private void label9_Click(object sender, EventArgs e)
        {
            if (first)
            {
                player1.Move(this, 8);
                first = false;
                Play(player1, player2);
                if (!gameOver && player2.GetType() == typeof(AI))
                {
                    player2.Move(this, 0);
                    first = true;
                    Play(player1, player2);
                }
            }
            else
            {
                player2.Move(this, 8);
                first = true;
                Play(player1, player2);
            }
            //Play(player1, player2);
        }

        private void Game_KeyPress(object sender, KeyPressEventArgs e)
        {
            
        }

        private void gameToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }

        private void tomatoToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.BackColor = Color.NavajoWhite;
            menuStrip1.BackColor = Color.NavajoWhite;
            statusStrip1.BackColor = Color.DarkSalmon;
            gameToolStripMenuItem.BackColor = Color.Tomato;
            helpToolStripMenuItem.BackColor = Color.Salmon;
            foreach (Label l in board)
            {
                l.ForeColor = Color.Tomato;
            }
        }

        private void gameToolStripMenuItem_MouseHover(object sender, EventArgs e)
        {
            gameToolStripMenuItem.ShowDropDown();
        }

        private void helpToolStripMenuItem_MouseHover(object sender, EventArgs e)
        {
            helpToolStripMenuItem.ShowDropDown();
        }

        private void blueberryToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.BackColor = Color.Lavender;
            menuStrip1.BackColor = Color.Lavender;
            statusStrip1.BackColor = Color.MediumSlateBlue;
            helpToolStripMenuItem.BackColor = Color.SlateBlue;
            gameToolStripMenuItem.BackColor = Color.DarkSlateBlue;
            foreach (Label l in board)
            {
                l.ForeColor = Color.DarkSlateBlue;
            }
        }

        private void grassToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.BackColor = Color.PaleGreen;
            menuStrip1.BackColor = Color.PaleGreen;
            statusStrip1.BackColor = Color.LimeGreen;
            helpToolStripMenuItem.BackColor = Color.LimeGreen;
            gameToolStripMenuItem.BackColor = Color.ForestGreen;
            foreach (Label l in board)
            {
                l.ForeColor = Color.ForestGreen;
            }
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            string message = "Are you sure you want to exit xO?";
            string caption = "Game Closing";
            MessageBoxButtons buttons = MessageBoxButtons.YesNo;
            DialogResult result;
            result = MessageBox.Show(message, caption, buttons);

            if (result == System.Windows.Forms.DialogResult.Yes)
            {
                Application.Exit();
            }
            
        }

        private void newGameToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ResetGame();
        }

        public void ResetGame()
        {
            gameOver = false;
            first = true;
            lastmoves = new string[9] { null, null, null, null, null, null, null, null, null };
            winner = Winner.None;
            if (playersToolStripMenuItem.Selected)
            {
                player1 = new Human("X");
                player2 = new Human("O");
            }
            else
            {
                player1 = new Human("X");
                player2 = new AI("O");
            }
            sekund = 0; minut = 0; stotinka = 0;
            timer1.Start();
            Play(player1,player2);
            foreach (Label l in board)
            {
                l.Enabled = true;
            }
        }

        private void againstComputerToolStripMenuItem_Click(object sender, EventArgs e)
        {
            againstComputerToolStripMenuItem.Select();
            ResetGame();
            
        }

        private void playersToolStripMenuItem_Click(object sender, EventArgs e)
        {
            playersToolStripMenuItem.Select();
            ResetGame();
        }
    }
}
